//
// Created by martin on 9/9/21.
//

#ifndef FTPSERVER2_0_HASHMAP_H
#define FTPSERVER2_0_HASHMAP_H

#include "utils.h"
#include "commontypes.h"


#define HASHMAP_LISTSIZE_INITIAL        16
#define HASHMAP_LAODFACTOR_INITIAL      0.75f

/**
 * hashmap存储项
 */
typedef struct entry {
    let key; /* 关键字 */
    let value; /* 值 */
    struct entry *next; /* 冲突链表 */
}*Entry;

#define newEntry() NEW(struct entry)
#define newEntryList(length) (Entry)malloc(sizeof(struct entry) * (length))

// 哈希结构
typedef struct hashmap *HashMap;
// 计算哈希值的函数类型
typedef int (*HashCode)(HashMap hashMap, let key);
// 判断key是否相等函数类型
typedef Boolean (*Equal)(let key1, let key2);
// 添加元素(key, value)函数类型
typedef void (*Put)(HashMap hashMap, let key, let value);
// 获取键对应值的函数类型
typedef let (*Get)(HashMap hashMap, let key);
// 删除指定键的函数类型
typedef Boolean (*Remove)(HashMap hashMap, let key);
// 清空所有元素
typedef void (*Clear)(HashMap hashMap);
// 判断指定key是否已存在的函数类型
typedef Boolean (*Exists)(HashMap hashMap, let key);

typedef Entry (*NewEntry)(let key, let value);
typedef void (*FreeEntry)(Entry *entry);

// 哈希结构
typedef struct hashmap {
    int size;              /* 当前map大小（所有元素个数） */
    int listSize;          /* 有效空间大小（数组大小） */
    Entry list;            /* 存储数组 */
    HashCode hashCode;     /* 计算哈希值 */
    Equal equal;           /* 判断键是否相等 */
    Put put;               /* 添加键、值对 */
    Get get;               /* 获取键对应值 */
    Remove remove;         /* 删除键 */
    Clear clear;           /* 清空map */
    Exists exists;         /* 判断键是否存在 */
    Boolean autoAssign;    /* 自动扩容 */
    int threadHold;        /* 扩容阈值 */
    float loadFactor;      /* 负载因子  */

    NewEntry newEntry;     /* 创建Entry */
    FreeEntry freeEntry;   /* 销毁Entry */
}*HashMap;

// 创建HashMap对象
HashMap createHashMap(HashCode hashCode, Equal equal);
// 释放HashMap对象
void freeHashMap(HashMap *hashMap);

/**
 * 迭代器结构
 * @note 迭代器总是指向下一个位置
 */
typedef struct hashmapiterator {
    Entry entry;           /* 迭代器当前指向的项 */
    int count;             /* 迭代次数 */
    int hashCode;          /* 键值对的哈希值, 即数组槽位 */
    HashMap hashMap;       /* 要迭代的map */
}*HashMapIterator;

#define newHashMapIterator() NEW(struct hashmapiterator)

HashMapIterator createHashMapIterator(HashMap hashMap);
Boolean hasNextHashMapIterator(HashMapIterator iterator);
HashMapIterator nextHashMapIterator(HashMapIterator iterator);
void freeHashMapIterator(HashMapIterator *iterator);

#endif //FTPSERVER2_0_HASHMAP_H
